import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { TreeSelect, Tooltip } from 'antd';

class TreeSelectItemC extends PureComponent {
  static defaultProps = {
    title: '',
    placeholder: '请选择',
    onChange: () => {},
    onSelect: () => {},
    onDeselect: () => {},
    onDropdownVisibleChange: () => {},
    onRef: () => {}, // 本组件的引用
    dataSource: [],
    treeCheckStrictly: false, // （父子节点选中状态不再关联），会使得 labelInValue 强制为 true
    ismultiple: false, // 默认不支持多选
    treeCheckable: false, // 默认不支持复选框
    allowClear: false, // 默认不支持删除
    treeDefaultExpandAll: false, // 默认不展开树节点
    showSearch: false, // 默认不显示查询框
    showCheckedStrategy: TreeSelect.SHOW_PARENT, // treeCheckable为true时，SHOW_PARENT生效
    maxTagCount: 1,
    disabled: false, // 默认不禁用
    positionBody: false, //  下拉框，默认跟随，如果select父节点有滚动，下拉框被遮挡，则需要设置为true
    onTreeExpand: () => {},
  };

  state = {
    value: undefined,
    showTooltip: true, // 下拉框展开时隐藏tooltip
    tooltipInfo: '', // 鼠标移动到组件，展示当前选中项全称
    dataSource: this.props.dataSource,
  };

  componentDidMount() {
    // 父组件对本组件的引用
    this.props.onRef(this);
    if (this.props.initialValue != undefined && this.props.initialValue != null) {
      this.onChangeInit(this.props.initialValue);
    }
  }

  componentDidUpdate(prevProps) {
    if (this.props.value) {
      const ds = prevProps.dataSource && prevProps.dataSource.length > 0 ? JSON.stringify(prevProps.dataSource) : '';
      const dsN = this.props.dataSource && this.props.dataSource.length > 0 ? JSON.stringify(this.props.dataSource) : '';
      const init = this.props.isMultiple ? (prevProps.value && prevProps.value.length > 0 ? JSON.stringify(prevProps.value) : '') : prevProps.value;
      const initN = this.props.isMultiple ? (this.props.value && this.props.value.length > 0 ? JSON.stringify(this.props.value) : '') : this.props.value;
      if (ds != dsN || init != initN) {
        this.setTooltip(this.props.value, this.props);
      }
      this.setState({
        value: this.props.value,
      });
    } else {
      this.setState({
        value: undefined,
        tooltipInfo: '', // 鼠标移动到组件，展示当前选中项全称
      });
    }
  }

  findtitle = (value, element) => {
    let arr = [];
    if (value && value.length) {
      const data = value.filter((children) => children.value == element);
      if (data && data.length) {
        arr = [...data];
      } else {
        value.map((item) => {
          arr = this.findtitle(item.children, element).length ? this.findtitle(item.children, element) : arr;
        });
      }
    }
    return arr;
  };

  // 设置tooltip
  setTooltip = (e, propT = this.props) => {
    const { dataSource, isMultiple } = propT;
    let tooltipInfo = '';
    if (e != undefined && e != null) {
      if (Array.isArray(e) && isMultiple) {
        // 多选
        e.forEach((element, index) => {
          const find = [];
          dataSource.map((item, i) => {
            if (item.value == element) {
              find.push(item);
            } else {
              const arr = this.findtitle(item.children, element);
              if (arr && arr.length > 0) {
                find.push(...arr);
              }
            }
          });

          if (find && find.length > 0) {
            tooltipInfo += find[0].title;
          }
          // 最后一个元素之后不用换行
          if (index != e.length - 1) {
            tooltipInfo += '\r\n';
          }
        });
      } else {
        // 单选
        const find = [];
        dataSource.map((item, i) => {
          if (item.value == e) {
            find.push(item);
          } else if (dataSource[i].children && dataSource[i].children.length > 0) {
            const data = dataSource[i].children.filter((children) => children.value == e);
            find.push(...data);
          }
        });
        if (find && find.length > 0) {
          tooltipInfo += find[0].title;
        }
      }
    }

    this.setState({
      tooltipInfo: tooltipInfo == '' ? '' : <div style={{ whiteSpace: 'pre' }}>{tooltipInfo}</div>,
    });
    return tooltipInfo == '' ? '' : <div style={{ whiteSpace: 'pre' }}>{tooltipInfo}</div>;
  };

  onChangeInit = (e, option) => {
    this.setState({
      value: e,
    });
    this.setTooltip(e);
  };

  // 响应下拉变更事件
  onChange = (e, option) => {
    this.setState({
      value: e,
    });
    this.props.onChange(e, option);
    this.setTooltip(e);
  };

  onDropdownVisibleChange = (open) => {
    this.setState({
      showTooltip: !open,
    });
    this.props.onDropdownVisibleChange();
  };

  render() {
    const {
      onTreeExpand,
      treeExpandedKeys,
      styleRow,
      initialValue,
      placeholder,
      onSelect,
      onDeselect,
      disabled,
      dataSource,
      isMultiple,
      treeCheckable,
      allowClear,
      treeDefaultExpandAll,
      showSearch,
      showCheckedStrategy,
      maxTagCount,
      filterTreeNode,
      onSearch,
      treeCheckStrictly,
      positionBody,
      switcherIcon,
    } = this.props;
    return (
      <Tooltip title={this.state.showTooltip ? this.state.tooltipInfo : ''}>
        <div>
          {initialValue ? (
            <TreeSelect
              getPopupContainer={(triggerNode) => (!positionBody ? triggerNode.parentNode : document.body)} // 菜单渲染父节点
              value={this.state.value} // 当前的选中
              treeCheckStrictly={treeCheckStrictly} // checkable 状态下节点选择完全受控（父子节点选中状态不再关联），会使得 labelInValue 强制为 true
              onSearch={onSearch} // 改变时回调
              filterTreeNode={filterTreeNode} // 是否根据输入项进行筛选
              maxTagCount={maxTagCount} // 最多显示多少个 tag
              placeholder={placeholder} // 占位符
              onChange={this.onChange} // 选中树节点时调用此函数
              onSelect={onSelect} // 选择值时触发此函数
              onDeselect={onDeselect} // 取消选择时触发此函数
              onDropdownVisibleChange={this.onDropdownVisibleChange} // 下拉框展开或关闭时触发此函数
              treeData={dataSource} // 数据源
              multiple={isMultiple} // 支持多选（当设置 treeCheckable 时自动变为 true）
              treeCheckable={treeCheckable} // 显示 checkbox
              allowClear={allowClear} // 显示清除按钮
              // treeDefaultExpandAll={true} // 默认展开所有树节点
              showSearch={isMultiple ? true : showSearch} // 是否支持搜索框
              showCheckedStrategy={showCheckedStrategy} // 定义选中项回填的方式.TreeSelect.SHOW_ALL: 显示所有选中节点(包括父节点). TreeSelect.SHOW_PARENT: 只显示父节点(当父节点下所有子节点都选中时). 默认只显示子节点.
              // searchPlaceholder='请输入查询条件' // 搜索框默认文字
              treeNodeFilterProp='title' // 输入项过滤对应的 treeNode 属性
              treeDefaultExpandedKeys={Array.isArray(initialValue) ? [...initialValue] : [initialValue]} // 默认展开的树节点
              disabled={disabled} // 禁用
              style={styleRow ? styleRow : { width: '100%' }}
              defaultValue={initialValue} // 默认值
              treeExpandedKeys={treeExpandedKeys} // 设置展开的树节点
              onTreeExpand={onTreeExpand} // 展示节点时调用
              switcherIcon={switcherIcon}
            />
          ) : (
            <TreeSelect
              getPopupContainer={(triggerNode) => (!positionBody ? triggerNode.parentNode : document.body)} // 菜单渲染父节点
              value={this.state.value} // 当前的选中
              treeCheckStrictly={treeCheckStrictly} // checkable 状态下节点选择完全受控（父子节点选中状态不再关联），会使得 labelInValue 强制为 true
              onSearch={onSearch} // 改变时回调
              filterTreeNode={filterTreeNode} // 是否根据输入项进行筛选
              maxTagCount={maxTagCount} // 最多显示多少个 tag
              placeholder={placeholder} // 占位符
              onChange={this.onChange} // 选中树节点时调用此函数
              onSelect={onSelect} // 选择值时触发此函数
              onDeselect={onDeselect} // 取消选择时触发此函数
              onDropdownVisibleChange={this.onDropdownVisibleChange} // 下拉框展开或关闭时触发此函数
              treeData={dataSource} // 数据源
              multiple={isMultiple} // 支持多选（当设置 treeCheckable 时自动变为 true）
              treeCheckable={treeCheckable} // 显示 checkbox
              allowClear={allowClear} // 显示清除按钮
              treeDefaultExpandAll={treeDefaultExpandAll} // 默认展开所有树节点
              showSearch={isMultiple ? true : showSearch} // 是否支持搜索框
              showCheckedStrategy={showCheckedStrategy} // 定义选中项回填的方式.TreeSelect.SHOW_ALL: 显示所有选中节点(包括父节点). TreeSelect.SHOW_PARENT: 只显示父节点(当父节点下所有子节点都选中时). 默认只显示子节点.
              // searchPlaceholder='请输入查询条件' // 搜索框默认文字
              treeNodeFilterProp='title' // 输入项过滤对应的 treeNode 属性
              // treeDefaultExpandedKeys={Array.isArray(initialValue) ? [...initialValue] : [initialValue]} // 默认展开的树节点
              disabled={disabled} // 禁用
              style={styleRow ? styleRow : { width: '100%' }}
              defaultValue={initialValue} // 默认值
              treeExpandedKeys={treeExpandedKeys} // 设置展开的树节点
              onTreeExpand={onTreeExpand} // 展示节点时调用
              switcherIcon={switcherIcon} // 折叠图标
            />
          )}
        </div>
      </Tooltip>
    );
  }
}

// props类型
TreeSelectItemC.propsTypes = {
  treeCheckStrictly: PropTypes.bool, // checkable 状态下节点选择完全受控（父子节点选中状态不再关联），会使得 labelInValue 强制为 true
  onSearch: PropTypes.func, // 改变时回调
  filterTreeNode: PropTypes.func, // 是否根据输入项进行筛选
  maxTagCount: PropTypes.number, // 最多显示多少个 tag
  placeholder: PropTypes.string, // 占位符
  onChange: PropTypes.func, // 选中树节点时调用此函数
  onSelect: PropTypes.func, // 选择值时触发此函数
  onDeselect: PropTypes.func, // 取消选择时触发此函数
  onDropdownVisibleChange: PropTypes.func, // 下拉框展开或关闭时触发此函数
  treeData: PropTypes.array, // 数据源
  multiple: PropTypes.bool, // 支持多选（当设置 treeCheckable 时自动变为 true）
  treeCheckable: PropTypes.bool, // 显示 checkbox
  allowClear: PropTypes.bool, // 显示清除按钮
  treeDefaultExpandAll: PropTypes.bool, // 默认展开所有树节点
  showSearch: PropTypes.bool, // 是否支持搜索框
  showCheckedStrategy: PropTypes.oneOf([TreeSelect.SHOW_PARENT, TreeSelect.SHOW_ALL, TreeSelect.SHOW_CHILD]), // 定义选中项回填的方式
  treeNodeFilterProp: PropTypes.string, // 输入项过滤对应的 treeNode 属性
  treeDefaultExpandedKeys: PropTypes.array, // 默认展开的树节点
  disabled: PropTypes.bool, // 禁用
  defaultValue: PropTypes.string, // 默认值
  treeExpandedKeys: PropTypes.string, // 设置展开的树节点
  onTreeExpand: PropTypes.func, // 展示节点时调用
  switcherIcon: PropTypes.any, // 折叠标签
};

export default TreeSelectItemC;
